<?PHP

/*
    classes:    ProjectPages
                ProjectPage
                ProtoPage
*/

require_once "helpers.inc";

class ProjectPage
{
    protected   $_row ;
    protected   $_projectid ;
    protected   $_pagecode ;
    protected   $_imagefilename ;

    public function ProjectPage($projectid, $pagecode, $username = null ) {
        global $DpDb;

        ! empty($projectid)
            or die( "Project id argument omitted." ) ;
        ! empty($pagecode)
            or die( "Page code argument omitted." ) ;

        $this->_projectid   = $projectid ;
        $this->_pagecode    = $pagecode ;
        $sql = SqlProjectPage($projectid, $pagecode, $username );
        // die(PrettySql($sql));
        $this->_row = $DpDb->SqlOneObject($sql)
            or die("PageClass::ProjectPage: "
                    . "Unable to fetch pages row ($projectid, $pagecode)." ) ;
    }

    protected function SetRow( &$row ) {
        $this->_row = $row ;
    }

    public function ProjectId() {
        return $this->_projectid ;
    }

    public function PageCode() {
        if( isset( $this->_pagecode ) )
            return $this->_pagecode ;
        else
            return $this->_row->pagecode ;
    }

    public function ProjectPath() {
        $path = ProjectPath($this->ProjectId());
        if(! file_exists($path)) {
            mkdir($path, 0777);
            permit_path($path);
        }
        file_exists( $path ) 
            or die( "ProjectPath failed: $path" ) ;
        return $path;
    }

    public function PagePath() {
        $path = ProjectPagePath( $this->ProjectId(), $this->PageCode() ) ;
        if(! file_exists($path)) {
            die( "no file $path");
            mkdir($path, 0777);
            permit_path($path);
        }
        file_exists( $path ) 
            or die( "PagePath failed: $path" ) ;
        return $path;
    }

    public function UserIsOwner() {
        global $User;
        return ( $User->UserName() == $this->UserName() ) ;
    }

    public function UserName() {
        return $this->_row->username ;
    }

    public function UserPageTaskId() {
        return $this->_row->pagetaskid ;
    }

    public function PrimaryLanguageCode() {
        return $this->_row->language;
    }

    public function Language() {
        return $this->PrimaryLanguageCode() ;
    }

    public function SecondaryLanguageCode() {
        return $this->_row->second_language;
    }

    public function CheckoutTime() {
        $ret = $this->_row->checkouttime ;
        return $ret ;
    }

    public function CompletionTime() {
        $ret = $this->_row->completiontime ;
        return $ret ;
    }

    public function IsCheckedOut() {
        return $this->CheckoutTime() > 0
            && $this->CompletionTime() == 0 ;
    }

    /*
    public function PageText() {
        if($this->IsTempText()) {
            return $this->TempText();
        }
        else {
            $v = $this->LatestVersion() ;
            return $v->PageText() ;
        }
    }
    */

    public function NewestPageText() {
        if( $this->IsTempText()) {
            $t = $this->TempText();
        }
        else {
            $vno = $this->MaxVersionNumber() ;
            $t = file_get_contents( PageVersionPath(
                    $this->ProjectId(), 
                    $this->PageCode(),
                    (string) (int) $vno ) ) ;
        }
        if($this->IsUnicode())
            return utf8_encode($t);
        else
            return $t;
    }

    public function LatestVersion() {
        static $_vsn ;
        require_once "PageVersionClass.inc" ;
        if( ! isset( $_vsn ) ) {
           $_vsn = new PageVersion( $this, $this->MaxVersionNumber() ) ;
        }
        return $_vsn ;
    }

    public function IsUnicode() {
        if(empty($this->_row->is_unicode))
            return false;
        else
            return true;
    }

    public function NameOfWork() {
        return $this->_row->nameofwork ;
    }

    public function AuthorsName() {
        return $this->_row->authorsname ;
    }

    public function ActiveTaskCode() {
        return $this->_row->taskcode ;
    }

    public function CharTableUrl() {
        return $this->_row->chartableurl ;
    }

    private function file_put( $path, $text ) {
        file_put_contents( $path, $text);
    }

    public function SaveTempText($text) {
        global $Context;
        $path = $this->_temp_path();
        $this->file_put( $path, $text ) ;
        file_exists( $path )
            or( "SetTempText error: $fpath" ) ;
        $Context->LogEvent($this->ProjectId(),
                            $this->PageCode(),
                            null,
                            null,
                            EVENT_SAVE_TEMP);
    }

    public function RemoveTempText() {
        if( $this->IsTempText() ) {
            $path = $this->_temp_path();
            unlink( $path ) ;
        }
    }

    private function _temp_path() {
        return $this->PagePath()."/temp.txt";
    }

    public function IsTempText() {
        return file_exists($this->_temp_path());
    }

    public function Version( $vnum ) {
        $projectid = $this->ProjectId() ;
        $pagecode = $this->PageCode() ;
        require_once "PageVersionClass.inc" ;
        return new PageVersion( $this, $vnum ) ;
    }

    public function InitTextFromPath($path) {
        $v = $this->Version( 0 ) ;
        $v->SetFromPath( $path );
    }

    public function DerivedImageFilePath() {
        $a = @$this->_row->imagefilename;
        $b = $this->_imagefilename;
        $fname = 
            ( ! empty($this->_row) && !empty($this->_row->imagefilename)
            ? $this->_row->imagefilename
            : $this->_imagefilename ) ;
        return build_path($this->PagePath(), $fname) ;
    }

    public function InitImageFromPath($path) {
        $topath = $this->DerivedImageFilePath();
        copy($path, $topath);
    }

    public function ImageFileName() {
        return (
            ! empty($this->_row->imagefilename) 
                ? $this->_row->imagefilename
                : $this->_imagefilename );
    }

    public function TextFileSize() {
        if(!file_exists($this->TextPath()))
            return 0 ;
        else
            return filesize($this->TextPath());
    }

    public function ImageFileSize() {
        if(!file_exists($this->ImageFilePath()))
            return 0 ;
        else
            return filesize($this->ImageFilePath());
    }

    public function TextFileUrl() {
        return PROJECTS_URL
            ."/".$this->ProjectId()
            ."/".$this->PageCode()
            ."/v0.txt";
    }

    public function ImageFilePath() {
        return build_path($this->PagePath(), $this->ImageFileName());
    }

    public function TextPath() {
        return build_path($this->PagePath(), "v0.txt");
    }

    public function ImageUrl() {
        return PROJECTS_URL
            ."/".$this->ProjectId()
            ."/".$this->PageCode()
            ."/".$this->ImageFileName() ;
    }

    public function MakeThumbnail() {
        //'find' the source image
        assert(file_exists($this->ImageFilePath()));
        $src_img = ImageCreateFrompng($this->ImageFilePath());

        //Get original image width and height
        $src_width = imagesx($src_img);
        $src_height = imagesy($src_img);

        //Our target output width
        //(image will scale down completely to this width)
        $dest_width = 125;

        //Calculate our output height proportionally
        $dest_height = $src_height * $dest_width / $src_width;

        // create a shell image
        $dest_img = imagecreate($dest_width, $dest_height); 

        imagecopyresampled($dest_img, $src_img, 
                            0, 0, 0 ,0, 
                            $dest_width, $dest_height, 
                            $src_width, $src_height); 

        //write it out
        imagepng($dest_img, $this->ThumbFilePath()); 

        //clean up memory
        imagedestroy($src_img); 
        imagedestroy($dest_img);
    }

    public function ThumbExists() {
        $path = $this->ThumbFilePath();
        return file_exists($path);
    }

    public function IsThumb() {
        return substr($this->_path, 0, 5) === "thumb";
    }

    public function ThumbFileName() {
        return "thumb.".$this->PageCode().".png";
    }

    // url to thumbnail, optional to create if necessary
    public function ThumbFilePath($ismake = false) {
        $path = build_path($this->PagePath(), $this->ThumbFileName());
        if((! file_exists($path)) && $ismake)
            $this->MakeThumbnail();
        return $path;
    }

    public function ThumbUrl($ismake = false) {
        if(! $this->ThumbExists() && $ismake)
            $this->MakeThumbnail();
        
        return PROJECTS_URL
            ."/".$this->ProjectId()
            ."/".$this->PageCode()
            ."/".$this->ThumbFileName();
    }

    public function ImageLink($prompt) {
        return '<a href="{this->ImageUrl()}"$prompt</a>\n';
    }

    public function ProjectUrl() {
        return "myproject.php?projectid={$this->_row->projectid}";
    }

    public function VersionCount() {
        return $this->_row->versioncount;
    }

    public function MaxVersionNumber() {
        static $id ;

        if( ! isset( $id ) ) {
            global $DpDb ;
            $projectid = $this->_projectid ;
            $pagecode  = $this->_pagecode ;
            $sql = "SELECT IFNULL( MAX( versionnumber ), 0 )
                    FROM pageversions AS pv
                    JOIN pagetasks AS pt 
                        ON pv.pagetaskid = pt.pagetaskid
                    WHERE pt.projectid = '$projectid'
                        AND pt.pagecode = '$pagecode'";
            $id = $DpDb->SqlOneValue( $sql ) ;
        }
        return $id ;
    }

    public function SourcePageCode() {
        return $this->_row->sourcepagecode;
    }

    public function ProjectComments() {
        return $this->_row->comments;
    }
    
    public function ProjectManager() {
        return $this->_row->projectmanager ;
    }

    public function Delete() {
        global $Context;
        global $DpDb;

        $sql = "DELETE FROM pages
                WHERE projectId = 'this->ProjectId()'
                AND pageCode = '$this->PageCode()'";
        $DpDb->SqlExecute($sql);
        // test the following for proper recursion
        unlink($this->PagePath());
        $Context->LogEvent($this->ProjectId(),
                            $this->PageCode(),
                            null,
                            null,
                            EVENT_DELETE_PAGE);
    }

    public function TempText() {
        if( ! $this->IsTempText())
            return "" ;

    $t = file_get_contents( $this->_temp_path() ) ;
    
    if($this->IsUnicode())
        return utf8_encode($t);
    else
        return $t;
    }
}

// A new page to be added from scratch
class ProtoPage extends ProjectPage
{
    public function ProtoPage($projectid, $pagecode, $imagefilename) {
        $this->_projectid       = $projectid ;
        $this->_pagecode        = $pagecode ;
        $this->_imagefilename   = $imagefilename ;
    }
}

// A page initialized from a query on projectid
/*
class RowPage extends ProjectPage
{
    public function RowPage($row) {
        // var_dump($row);
        $this->_projectid = $row->projectid;
        $this->_pagecode = $row->pagecode;
        $this->_row = $row ;
    }

    public function TaskCode() {
        return $this->_row->taskcode ;
    }
}
*/

/*
class ProjectPages
{
    protected   $_projectid;
    protected   $_project_pages = array();
    protected   $_exists = false ;

    public function ProjectPages($projectid) {
        global $DpDb;

        $this->_projectid = $projectid;
        !empty($projectid)
            or die("ProjectPages with null projectid.");
        $rows = $this->SqlProjectPages( $projectid ) ;

        if( count( $rows ) == 0 ) {
            return ;
        }

        $this->_exists = true ;
        foreach($rows as $row) {
            $code = $row->pagecode;
            $this->_project_pages[$code] = new RowPage($row) ;
        }
        assert(count($this->_project_pages) == count($rows));
    }

    public function ProjectId() {
        return $this->_projectid;
    }

    public function Exists() {
        return $this->_exists;
    }

    public function Rows() {
        return $this->_project_pages;
    }

    public function ProjectPath() {
        return ProjectPath($this->_row->_projectid);
    }

    public function Page($pagecode) {
        assert(! empty( $pagecode ) ) ;
        $pg = @$this->_project_pages[$pagecode];
        return empty( $pg ) ? null : $pg ;
    }

    public function AddFromFilesets($sets) {
        foreach($sets as $set) {
            $this->AddFromFileset($set);
        }
    }

    public function AddFromFileset($set) {
        $projectid      = $this->ProjectId();
        $pagecode       = $set->PageCode();
        $imagename      = $set->ImageFileName();
        $textpath       = $set->TextFilePath();
        $imagepath      = $set->ImageFilePath();

        $pg = new ProtoPage($projectid, $pagecode, $imagename);
        $pg->InitTextFromPath($textpath);
        $pg->InitImageFromPath($imagepath);
        $this->_project_pages[$pagecode] = $pg;
        $this->AddPageRecord($projectid, $pagecode, $imagename);
    }

    public function AddPageRecord($projectid, $pagecode, $imagefilename) {
        global $DpDb;
        $sql = "REPLACE INTO pages
                (   projectid,
                    pagecode,
                    imageFileName
                ) VALUES
                ('  '$projectid',
                    '$pagecode',
                    '$imagefilename'
                )";
        $i = $DpDb->SqlExecute($sql);
    }

    public function MakeThumbnails() {
        foreach($this->_project_pages as $pg) {
            $pg->MakeThumbnail(true);
        }
    }
    
    public function Count() {
        return count($this->_project_pages);
    }
    
    public function DeleteAll() {
        global $DpDb;

        $sql = "DELETE FROM pages
                WHERE projectId = '{$this->ProjectId()}'";
        $DpDb->SqlExecute($sql);
    }

    function SqlProjectPageTasks($projectid) {
        global $DpDb ;
        $sql = "SELECT
                    p.nameofwork,
                    p.authorsname,
                    p.chartableurl,
                    pp.projectid,
                    pp.pagecode,
                    pp.imagefilename,
                    pt.taskcode,
                    pt.username,
                    pt.completiontime,
                    pt.checkouttime,
                    COALESCE(pt.completiontime,
                             pt.checkouttime) AS tasktime,
                    CASE WHEN EXISTS
                    (   SELECT 1 FROM pagetasks AS ptdiff
                        WHERE projectid = pt.projectid 
                            AND pagecode = pt.pagecode
                            AND completiontime > pt.completiontime
                            AND NOT completiontime IS NULL
                    ) THEN 1 ELSE 0 END AS isdiff
                FROM
                    pages AS pp
                JOIN
                    projects AS p
                ON
                    pp.projectid = p.projectid
                LEFT JOIN
                    pagetasks AS pt
                ON
                    pp.projectid = pt.projectid
                    AND pp.pagecode = pt.pagecode
                    AND pt.username IS NOT NULL
                LEFT JOIN
                    tasks as t
                ON
                    pt.taskcode = t.taskcode
                WHERE
                    pp.projectid = '$projectid'
                ORDER BY
                    pp.pagecode,
                    pt.sequencenumber\n";
        // die( PrettySql( $sql ) ) ;
        return $DpDb->SqlObjects( $sql ) ;
    }
}
*/

function SqlProjectPage($projectid, $pagecode, $username = null ) {
    $usql = empty($username) ? "" : "\nAND pt.username = '$username'"; 
    return "SELECT
                pp.projectid,
                pp.pagecode,
                pp.imagefilename,
                pp.sourcepagecode,
                p.language,
                p.second_language,
                p.comments,
                p.username AS projectmanager,
                p.nameofwork,
                p.authorsname,
                p.chartableurl,
                p.is_unicode,
                pt.taskcode,
                pt.username,
                pt.pagetaskid,
                pt.checkouttime,
                pt.completiontime,
                (       
                    SELECT COUNT(*)
                    FROM pageversions
                    WHERE pagetaskid = pt.pagetaskid
                ) AS versioncount
            FROM
                pages AS pp
            JOIN
                projects AS p
            ON
                pp.projectid = p.projectid

            LEFT JOIN
                pagetasks AS pt
            ON
                pp.projectid = pt.projectid
                AND pp.pagecode = pt.pagecode
                AND NOT pt.checkouttime IS NULL
            WHERE
                pp.projectid = '$projectid'
                AND pp.pagecode = '$pagecode'
                $usql
            GROUP BY
                pp.projectid, pp.pagecode
            ORDER BY
                pt.completiontime DESC\n";
}

?>
